package com.ym.b2b.upload.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.servlet.http.HttpServletRequest;

import net.coobird.thumbnailator.Thumbnails;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import util.PlUploadUtil;

import com.ym.b2b.commons.controller.BaseController;
import com.ym.b2b.commons.exception.BaseException;
import com.ym.b2b.upload.service.EmBUploadService;
import com.ym.b2b.upload.sqlbean.EmBUpload;
import com.zc.commons.base.Page;
import com.zc.commons.base.Result;
import com.zc.commons.util.ZcStringUtil;
import com.zc.export.ExcelUtil;

/**
 * @ClassName: ManagerUploadController
 * @Description: 上传功能处理
 * @Author chinavane
 * @Date 2015年1月9日 下午12:40:31
 * @Modify
 * @CopyRight 珍诚医药在线股份有限公司
 */
@Controller
@RequestMapping("/upload")
public class ManagerUploadController extends BaseController {

    @Autowired
    private EmBUploadService    emBUploadService;

    // 上传参数
    private Map<String, String> uploadParams;

    // 文件上传业务类
    @RequestMapping("uploadFiles.do")
    @ResponseBody
    public Result uploadFiles(HttpServletRequest request, EmBUpload emBUpload) {

        Result ret = checkParams(emBUpload);// 检查输入参数
        if (ret.getCode().equals(Result.CODE_100)) return ret;

        try {
            // 获取配置文件参数
            uploadParams = PlUploadUtil.getInstance(request.getSession().getServletContext().getRealPath(emBUpload.getPlugPath())).getUploadParam();
            ret = doUpload(request, emBUpload);
        } catch (Exception e) {
            e.printStackTrace();
            ret.setCodeResult(Result.CODE_100, e.getMessage());
        }
        return ret;
    }

    private Result checkParams(EmBUpload emBUpload) {
        Result ret = new Result();
        if (StringUtils.isBlank(emBUpload.getModuleId())) {
            ret.setCodeResult(Result.CODE_100, "模块moduleId 不能为空!");
            return ret;
        }
        if (StringUtils.isBlank(emBUpload.getFuncId())) {
            ret.setCodeResult(Result.CODE_100, "功能funcId 不能为空!");
            return ret;
        }
        if (StringUtils.isBlank(emBUpload.getPlugPath())) {
            ret.setCodeResult(Result.CODE_100, "JS插件目录plugPath 未指定!");
            return ret;
        }
        return ret;
    }

    /**
     * @Title: upload
     * @Description: TODO
     * @Param @param request
     * @Param @param response
     * @Param @param emBUpload
     * @Param @throws IOException
     * @Return void
     * @Throws
     */
    @SuppressWarnings("unchecked")
    private Result doUpload(HttpServletRequest request, EmBUpload emBUpload) throws BaseException {
        Result ret = new Result();
        String name = null;// 文件名
        BufferedOutputStream outputStream = null;
        if (ServletFileUpload.isMultipartContent(request)) {
            try {
                DiskFileItemFactory factory = new DiskFileItemFactory();
                factory.setSizeThreshold(1024);
                ServletFileUpload upload = new ServletFileUpload(factory);
                upload.setHeaderEncoding("UTF-8");
                upload.setSizeMax(Integer.valueOf(uploadParams.get("allow-size")) * 1024 * 1024);// 设置上传大小
                List<FileItem> items = upload.parseRequest(request);
                // 生成新文件名
                String newFileName = null;

                for (FileItem item : items) {
                    String itemUploadPath = checkSaveDir(request)[0];

                    if (!item.isFormField()) {// 如果是文件类型
                        name = item.getName();// 获得文件名

                        // 文件名64位加密
                        newFileName = PlUploadUtil.getBASE64(FilenameUtils.getBaseName(name)).replace("/", "").concat(".").concat(FilenameUtils.getExtension(name).toLowerCase());

                        // 是否覆盖原文件，不覆盖则重命名一个时间戳
                        boolean existFlag = false;
                        if (Boolean.valueOf(uploadParams.get("isRecover"))) {
                            File currentFile = new File(itemUploadPath + "/" + newFileName);
                            if (currentFile.exists()) {
                                existFlag = true;
                                Calendar calendar = Calendar.getInstance();
                                String extens = "" + calendar.get(Calendar.YEAR) + calendar.get(Calendar.MONTH)
                                                + calendar.get(Calendar.DATE) + calendar.get(Calendar.HOUR)
                                                + calendar.get(Calendar.MINUTE) + calendar.get(Calendar.SECOND);
                                newFileName = FilenameUtils.getBaseName(newFileName).concat("_" + extens + ".").concat(FilenameUtils.getExtension(newFileName).toLowerCase());
                            }
                        }

                        if (newFileName != null) {
                            if (existFlag == true
                                && newFileName.equals(PlUploadUtil.getBASE64(FilenameUtils.getBaseName(name)))) {
                                continue;
                            }
                            File savedFile = new File(itemUploadPath, newFileName);
                            item.write(savedFile);
                            emBUpload.setFileSysName(newFileName);
                            emBUpload.setFileName(FilenameUtils.getBaseName(name));
                            emBUpload.setFileExtensions(FilenameUtils.getExtension(name));
                            // 判断文件是否为图片，并生成相应的缩略图
                            // 缩略图jar包 https://code.google.com/p/thumbnailator/
                            ImageInputStream iis = ImageIO.createImageInputStream(savedFile);
                            Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);

                            if (iter.hasNext()) {
                                emBUpload.setFileType("img");
                                if (!(ZcStringUtil.isNotBlank(emBUpload.getIsPicZoom()) && emBUpload.getIsPicZoom().equals("true"))) {

                                    Integer thumb_small_width = Integer.valueOf(uploadParams.get("thumbSmallWidth"));
                                    Integer thumb_small_height = Integer.valueOf(uploadParams.get("thumbSmallHeight"));

                                    Integer thumb_middle_width = Integer.valueOf(uploadParams.get("thumbMiddleWidth"));
                                    Integer thumb_middle_height = Integer.valueOf(uploadParams.get("thumbMiddleHeight"));

                                    Integer thumb_big_width = Integer.valueOf(uploadParams.get("thumbBigWidth"));
                                    Integer thumb_big_height = Integer.valueOf(uploadParams.get("thumbBigHeight"));

                                    Boolean thumbSmall = Boolean.valueOf(uploadParams.get("thumbSmall"));
                                    Boolean thumbMiddle = Boolean.valueOf(uploadParams.get("thumbMiddle"));
                                    Boolean thumbBig = Boolean.valueOf(uploadParams.get("thumbBig"));

                                    if (thumbSmall) {
                                        Thumbnails.of(new File(itemUploadPath + "/" + newFileName)).size(thumb_small_width,
                                                                                                         thumb_small_height).toFile(new File(
                                                                                                                                             itemUploadPath
                                                                                                                                                     + "/"
                                                                                                                                                     + "small_"
                                                                                                                                                     + newFileName));
                                    }

                                    if (thumbMiddle) {
                                        Thumbnails.of(new File(itemUploadPath + "/" + newFileName)).size(thumb_middle_width,
                                                                                                         thumb_middle_height).toFile(new File(
                                                                                                                                              itemUploadPath
                                                                                                                                                      + "/"
                                                                                                                                                      + "middle_"
                                                                                                                                                      + newFileName));
                                    }

                                    if (thumbBig) {
                                        Thumbnails.of(new File(itemUploadPath + "/" + newFileName)).size(thumb_big_width,
                                                                                                         thumb_big_height).toFile(new File(
                                                                                                                                           itemUploadPath
                                                                                                                                                   + "/"
                                                                                                                                                   + "big_"
                                                                                                                                                   + newFileName));
                                    }
                                }
                            }

                            emBUpload.setFileSize(item.getSize());
                            emBUpload.setFileIcons(emBUpload.getPlugPath() + "/icons/"
                                                   + emBUpload.getFileExtensions().toLowerCase() + ".png");
                            emBUpload.setFilePath(itemUploadPath + "/" + newFileName);
                            emBUpload.setRelativeFilePath(checkSaveDir(request)[1]);
                            emBUpload.setCreatedBy(getManagerTokenUser(request).getUserName());
                            emBUploadService.insertEmBUpload(emBUpload);

                        }
                    }
                }
                // ret.setResult("{\"status\":true,\"newName\":\"" + newFileName + "\"}");
            } catch (Exception e) {
                e.printStackTrace();
                throw new BaseException("上传文件失败, 异常信息：" + e.getMessage());
            } finally {
                try {
                    if (outputStream != null) outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return ret;
    }

    // 列表查询

    @RequestMapping("searchPageEmBUpload.do")
    @ResponseBody
    public Result searchPageEmBUpload(EmBUpload emBUpload, Page<EmBUpload> page, HttpServletRequest req) {
        Result result = new Result();
        result = emBUploadService.searchPageEmBUpload(emBUpload, page);
        return result;
    }

    // 导出站点资料
    @RequestMapping(value = "searchPageWebImformationExcel.do")
    @ResponseBody
    public Result searchPageWebImformationExcel(EmBUpload emBUpload, Page<EmBUpload> page, String loadType) {
        Result ret = new Result();
        try {
            if (loadType == null || loadType.equals("")) {
                ret.setCode(Result.CODE_100);
                ret.setResult("loadType 参数 '数量'  不能为空!");
                return ret;
            }
            page.setPageable("true");
            page.setPageSize(Integer.parseInt(loadType));
            page.setStartRow(1);
            ret = emBUploadService.searchPageEmBUpload(emBUpload, page);
            ExcelUtil<EmBUpload> excelUtil = new ExcelUtil<EmBUpload>();
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("model", ret.getRows());
            ret = excelUtil.createExcel("webInformationListExcel", map);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            ret.setCodeResult(Result.CODE_100, e.getMessage());
        }
        return ret;
    }

    // 获取单条记录内容
    @RequestMapping("searchEmBUpload.do")
    @ResponseBody
    public EmBUpload searchEmBUpload(EmBUpload emBUpload, HttpServletRequest req) {
        EmBUpload result = new EmBUpload();
        result = emBUploadService.searchEmBUpload(emBUpload);
        return result;
    }

    // 删除多条记录内容
    @RequestMapping("deleteMultipleEmBUpload.do")
    @ResponseBody
    public Result deleteMultipleEmBUpload(String uploadIdList, HttpServletRequest req) {
        Result result = new Result();
        try {
            emBUploadService.deleteMultipleEmBUpload(uploadIdList);
        } catch (Exception e) {
            // TODO: handle exception
            result.setCode("100");
            return result;
        }
        result.setCode("200");
        return result;
    }

    /**
     * @param request 请求对象
     * @return 目录路径
     * <p>
     * 用来检查文件存放路径是否存在，不存在则创立
     * </p>
     */
    protected String[] checkSaveDir(HttpServletRequest request) {
        String moudleId = request.getParameter("moduleId");
        String funcId = request.getParameter("funcId");
        Calendar calendar = Calendar.getInstance();
        String year = String.valueOf(calendar.get(Calendar.YEAR));
        String month = String.valueOf(calendar.get(Calendar.MONTH));
        String day = String.valueOf(calendar.get(Calendar.DATE));
        String filePath = request.getSession().getServletContext().getRealPath(uploadParams.get("filePath"));
        String relativeFilePath = uploadParams.get("relativeFilePath");

        String dirPath = filePath;
        String dirRelativeFilePath = relativeFilePath;
        // 目录结构
        if (Boolean.valueOf(uploadParams.get("isModule"))) {
            dirPath += "\\" + moudleId;
            dirRelativeFilePath += "/" + moudleId;
        }
        if (Boolean.valueOf(uploadParams.get("isFunction"))) {
            dirPath += "\\" + funcId;
            dirRelativeFilePath += "/" + funcId;
        }
        if (Boolean.valueOf(uploadParams.get("isYear"))) {
            dirPath += "\\" + year;
            dirRelativeFilePath += "/" + year;
        }
        if (Boolean.valueOf(uploadParams.get("isMonth"))) {
            dirPath += "\\" + month;
            dirRelativeFilePath += "/" + month;
        }
        if (Boolean.valueOf(uploadParams.get("isDay"))) {
            dirPath += "\\" + day;
            dirRelativeFilePath += "/" + day;
        }

        checkDirExist(dirPath);
        String[] dirString = new String[2];
        dirString[0] = dirPath;
        dirString[1] = dirRelativeFilePath + "/";
        return dirString;

    }

    /**
     * @param dirPath 文件目录
     * <p>
     * 用于检查目录是否存在，没有时创建
     * </p>
     */
    protected void checkDirExist(String dirPath) {
        File dir = new File(dirPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
    }

}
